package org.phalanx.messenging;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

import org.phalanx.map.MapCoordinates;
import org.phalanx.map.MapTile;
import org.phalanx.map.MapTileSet;
import org.phalanx.map.PhalanxMap;

public class PhalanxMapDataMessage extends AbstractMessage {
	
	public PhalanxMapDataMessage(){
		this.setMessageHeader("mapdownload");
	}
	
	public void setPhalanxMapData(PhalanxMap pMap){
		MapTileSet tileSet = pMap.getMapTileSet();
		
		String tileSetData = serializeTileSetData(tileSet); // TODO : We may not need this
		
		this.setToMessage("tilesetdata", tileSetData);
		this.setToMessage("tilesetname", tileSet.getTileSetName());
		this.setToMessage("mapname", pMap.getMapName()); // TODO fix mapname issue
/*		if (pMap.getAuthorName() != null && !pMap.getAuthorName().isEmpty()){
			this.setToMessage("authorname", pMap.getAuthorName());
		}
		if (pMap.getAuthorCountry() != null && !pMap.getAuthorCountry().isEmpty()){
			this.setToMessage("country", pMap.getAuthorCountry());
		}*/
		this.setToMessage("l", pMap.getMapLength().toString());
		this.setToMessage("w", pMap.getMapWidth().toString());
		this.setToMessage("defaulttile", tileSet.getTerrainRefNameFromTile(pMap.getDefaultTile()));
		this.setToMessage("tilesize", pMap.getTileSize().toString());
		
		if (!pMap.getBuildPoints().isEmpty()){
			this.setToMessage("buildpoints", serializeBuildPoints(pMap));
		}
		this.setToMessage("mapdata", serializeMapData(pMap));
	}
	
	private String serializeBuildPoints(PhalanxMap pMap){
		StringBuffer buildPointsStr = new StringBuffer();
		
		ArrayList<MapCoordinates> bpArray = pMap.getBuildPoints();
		
		Iterator<MapCoordinates> i = bpArray.iterator();
		boolean first = true;
		
		while (i.hasNext()){
			MapCoordinates c = i.next();
			
			if (!first){
				buildPointsStr.append(":");
			} else {
				first = false;
			}
			
			buildPointsStr.append("{");
			buildPointsStr.append(c.getX().toString());
			buildPointsStr.append("!");
			buildPointsStr.append(c.getY().toString());
			buildPointsStr.append("}");
		}
		
		return buildPointsStr.toString();
	}
	
	private String serializeTileSetData(MapTileSet tileSet){
		StringBuffer tileSetString = new StringBuffer();
		
		Set<String> s = tileSet.getMapTileSetTable().keySet();
		Iterator<String> i = s.iterator();
		boolean first = true;
		
		while (i.hasNext()){
			String tileName = i.next();
			String terrain = tileSet.getMapTileByName(tileName).getTerrain().getTerrainType();
			String imageReference = tileSet.getMapTileByName(tileName).getImageReference();
			
			if (!first){
				tileSetString.append(":");
			} else {
				first = false;
			}
			
			tileSetString.append("{");
			tileSetString.append(tileName);
			tileSetString.append("!");
			tileSetString.append(terrain);
			tileSetString.append("!");
			tileSetString.append(imageReference);
			tileSetString.append("}");
		}
		
		return tileSetString.toString();
	}
	
	private String serializeMapData(PhalanxMap pMap){
		StringBuffer mapDataStr = new StringBuffer();
		boolean first = true;
		for (int i = 0; i < pMap.getMapLength(); i++){
			for (int j = 0; j < pMap.getMapWidth(); j++){
				MapTile t = pMap.getMapTileAt(j,i);
				
				String refName = pMap.getMapTileSet().getTerrainRefNameFromTile(t);
				
				if (refName != null && !refName.equals(pMap.getMapTileSet().getTerrainRefNameFromTile(pMap.getDefaultTile()))){
					if (!first){
						mapDataStr.append(":");
					}else {
						first = false;
					}

					mapDataStr.append("{");
					mapDataStr.append(j + "");
					mapDataStr.append("!");
					mapDataStr.append(i + "");
					mapDataStr.append("!");
					mapDataStr.append(refName);
					mapDataStr.append("}");
				}
			}
		}
		
		return mapDataStr.toString();
	}
}
